home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
C++
/
Frameworks
/
Argus Frameworks 2.1
/
Argus Libraries 2.1
/
FnTE.cp
< prev
Wrap
Text File
|
1996-01-02
|
21KB
|
716 lines
/**********************************************************************
FnTE.cp
***********************************************************************/
/*
Displaying text should be easier than it is. This library
provides a group of functions which allow the basics of displaying
and editing of text in the form of a TE Record.
Functions Include:
FnTE_SetUpTEWindow Creates TE Record to fill window
FnTE_MaintainCursor Call this and TEIdle() in event loop
FnTE_UpdateWindow Redraws window contents
FnTE_DoActivate Activates/Deactivates window
FnTE_DoKeyDown Handles keyboard inputs
FnTE_DoEditMenu Handles cut and paste of TE data
FnTE_DoContent Handles mousedown in window
FnTE_DetSBarIncr Refreshes scroll bar parameters
FnTE_GrowWindow Handles resizing of window
FnTE_FrameRect Puts frame around text in window
FnTE_GetTEXT Puts TEXT resource into TE Record
// Semi-private
FnTE_AdjustText
FnTE_SetToCursorPos
FnTE_CheckScrollBar
FnTE_ScrollProc
*/
#define FnCUT 1
#define FnCOPY 2
#define FnPASTE 3
#define FnCLEAR 4
#define FnSELECT_ALL 5
#define DEL_KEY 8
#define DOWN_ARROW 31
#define UP_ARROW 30
#define LEFT_ARROW 28
#define RIGHT_ARROW 29
#define PAGE_DOWN 12
#define PAGE_UP 11
#define HOME 1
#define END 4
#define MAX_CHAR 32000
TEHandle *tempTEHptr;
ControlHandle *tempVScrollptr;
Cursor IBeamCursor;
Boolean IBeamCursorDefined = FALSE;
// Prototypes
Boolean FnTE_SetUpTEWindow ( WindowPtr w,
Boolean hasGrowIcon,
Boolean wordWrap,
short font,
short textSize,
short textInsetPixels,
// results //
TEHandle *te,
ControlHandle *vScroll );
void FnTE_MaintainCursor ( WindowPtr w,
TEHandle *te );
void FnTE_UpdateWindow ( WindowPtr w,
TEHandle *te,
Boolean hasGrowIcon );
void FnTE_DoActivate ( WindowPtr w,
TEHandle *te,
ControlHandle *vScroll,
Boolean hasGrowIcon,
Boolean activate );
void FnTE_DoKeyDown ( char theChar,
TEHandle *te,
ControlHandle *vScroll,
char *dirty );
void FnTE_DoEditMenu ( int item,
TEHandle *te,
ControlHandle *vScroll,
char *dirty,
int cutCommand,
int copyCommand,
int pasteCommand,
int clearCommand,
int selectAllCommand );
void FnTE_DoContent ( WindowPtr w,
EventRecord *e,
TEHandle *te,
ControlHandle *vScroll );
void FnTE_DetSBarIncr ( TEHandle *te,
ControlHandle *vScroll );
void FnTE_GrowWindow ( WindowPtr w,
TEHandle *te,
ControlHandle *vScroll,
short textInsetPixels,
Point clickLoc );
void FnTE_FrameRect ( WindowPtr w,
TEHandle *te,
short inset );
void FnTE_GetTEXT ( short rsrcID,
TEHandle *te,
ControlHandle *vScroll );
void FnTE_AdjustText ( TEHandle *te, ControlHandle *vScroll );
void FnTE_SetToCursorPos ( TEHandle *te, ControlHandle *vScroll );
void FnTE_CheckScrollBar ( TEHandle *te, ControlHandle *vScroll );
pascal void FnTE_ScrollProc ( ControlHandle theControl,
short theCode );
extern void FnErr_DisplayStr( Str255 s1,
Str255 s2,
Str255 s3,
Str255 s4,
int quitFlag );
/********** SetUpTEWindow */
Boolean FnTE_SetUpTEWindow(
WindowPtr w,
Boolean hasGrowIcon,
Boolean wordWrap,
short font,
short textSize,
short textInsetPixels,
// results //
TEHandle *te,
ControlHandle *vScroll )
/*
FnSetUpWindow takes information you supply about a window
and it's default text parameters then returns a TEHandle to
a text pane that fills the window and a ControlHandle to
a scroll bar that is located at the right of the window.
Returns FALSE if error detected during routine.
*/
{
Rect destRect, viewRect;
Rect vSBarRect;
GrafPtr oldPort;
int SBarWidth = 15;
// define basic te stuff
GetPort( &oldPort );
SetPort( w );
TextFont( font );
TextSize( textSize );
// set scroll bar rect
vSBarRect = (*w).portRect;
vSBarRect.left = vSBarRect.right - SBarWidth;
vSBarRect.right += 1;
vSBarRect.top -= 1;
if( hasGrowIcon )
vSBarRect.bottom -= 14;
else
vSBarRect.bottom += 1;
// create new control
*vScroll = NewControl( w, &vSBarRect, "\p", 1, 0, 0, 0,
scrollBarProc, 0L);
if( *vScroll == NULL )
return FALSE;
// define te view and dest rects
viewRect = w->portRect;
viewRect.right -= SBarWidth;
if( hasGrowIcon )
viewRect.bottom -= SBarWidth;
InsetRect(&viewRect, textInsetPixels, textInsetPixels);
destRect = viewRect;
// create new te record
*te = TENew( &destRect, &viewRect );
if( *te == NULL )
return FALSE;
if( wordWrap )
(***te).crOnly = 1;
else
(***te).crOnly = -1;
// set autoview flag for automatic scrolling
TEAutoView( TRUE, *te );
SetPort( oldPort );
return TRUE;
}
/********** MaintainCursor */
void FnTE_MaintainCursor( WindowPtr w, TEHandle *te )
/*
Maintains cursor icon in TE window. Call this function each time
through event loop (also call Macintosh function TEIdle to blink
cursor).
*/
{
Point pt;
WindowPeek wPtr;
GrafPtr savePort;
CursHandle hCurs;
/*
Variables hIBeamCursor and IBeamCursorDefined must be defined
at top of this FnTELibrary.c file.
*/
if( !IBeamCursorDefined )
{
hCurs = GetCursor(1); /* IBeam Cusor ID */
IBeamCursor = **hCurs;
IBeamCursorDefined = TRUE;
}
wPtr = (WindowPeek)FrontWindow();
if( (WindowPtr)wPtr == w )
{
if( wPtr->windowKind >= 0 )
{
GetPort( &savePort );
SetPort( (GrafPtr)wPtr );
GetMouse( &pt );
if( PtInRect( pt, &(***te).viewRect ) )
{
SetCursor( &IBeamCursor );
}
else
{
SetCursor( &qd.arrow );
}
SetPort( savePort );
}
}
}
/********** UpdateWindow */
void FnTE_UpdateWindow( WindowPtr w, TEHandle *te, Boolean hasGrowIcon )
/*
Updates a text window.
*/
{
GrafPtr savePort;
GetPort(&savePort);
SetPort(w);
BeginUpdate(w);
EraseRect(&w->portRect);
DrawControls(w);
if( hasGrowIcon )
DrawGrowIcon(w);
TEUpdate(&w->portRect, *te);
EndUpdate(w);
SetPort(savePort);
}
/********** DoActivate */
void FnTE_DoActivate( WindowPtr w,
TEHandle *te,
ControlHandle *vScroll,
Boolean hasGrowIcon,
Boolean activate )
/*
Handles activateEvt for TE window.
*/
{
if( activate )
{
TEActivate( *te );
ShowControl( *vScroll );
if( hasGrowIcon ) DrawGrowIcon( w );
TEFromScrap();
}
else
{
TEDeactivate( *te );
HideControl( *vScroll );
if( hasGrowIcon ) DrawGrowIcon( w );
ZeroScrap();
TEToScrap();
}
}
/********** DoKeyDown */
void FnTE_DoKeyDown( char theChar,
TEHandle *te,
ControlHandle *vScroll,
char *dirty )
/*
Handles key press in TE region. Uses functions FnTE_SetToCursorPos
and FnTE_AdjustText to postion text and scroll bar.
*/
{
int count = 256; // same as used in FnIO_Library
tempTEHptr = te; // used in Scroll_Proc
tempVScrollptr = vScroll; // used in Scroll_Proc
if( (((***te).teLength + count) >= MAX_CHAR) &&
(theChar != DEL_KEY) )
{
FnErr_DisplayStr(
"\pFile size limits have been exceeded. ",
"\pPlease save your work and then try to ",
"\preduce file size.",
"\p",
FALSE ); // don't quit
}
else
{
switch( theChar )
{
case DOWN_ARROW:
case UP_ARROW:
case LEFT_ARROW:
case RIGHT_ARROW:
TEKey( theChar, *te );
FnTE_SetToCursorPos( te, vScroll );
FnTE_AdjustText( te, vScroll );
break;
case PAGE_DOWN:
FnTE_ScrollProc( *vScroll, (short)inPageDown );
break;
case PAGE_UP:
FnTE_ScrollProc( *vScroll, (short)inPageUp );
break;
case HOME:
SetCtlValue( *vScroll, 0 );
FnTE_AdjustText( te, vScroll );
break;
case END:
SetCtlValue( *vScroll, GetCtlMax(*vScroll) );
FnTE_AdjustText( te, vScroll );
break;
default:
{
TEKey( theChar, *te );
FnTE_SetToCursorPos( te, vScroll );
FnTE_AdjustText( te, vScroll );
*dirty = 1;
}
}
}
}
/********** DoEditMenu */
void FnTE_DoEditMenu( int theItem,
TEHandle *te,
ControlHandle *vScroll,
char *dirty,
int cutCommand,
int copyCommand,
int pasteCommand,
int clearCommand,
int selectAll )
/*
Performs cut and paste function of standard Edit menu items.
*/
{
if ( theItem == cutCommand ) theItem = FnCUT;
else if( theItem == copyCommand ) theItem = FnCOPY;
else if( theItem == pasteCommand ) theItem = FnPASTE;
else if( theItem == clearCommand ) theItem = FnCLEAR;
else if( theItem == selectAll ) theItem = FnSELECT_ALL;
switch( theItem )
{
case FnCUT:
TECut( *te );
FnTE_DetSBarIncr( te, vScroll );
FnTE_SetToCursorPos( te, vScroll );
FnTE_AdjustText( te, vScroll );
*dirty = 1;
break;
case FnCOPY:
TECopy( *te );
break;
case FnPASTE:
if(TEGetScrapLen() + (***te).teLength < MAX_CHAR)
{
TEPaste( *te );
FnTE_DetSBarIncr( te, vScroll );
FnTE_SetToCursorPos( te, vScroll );
FnTE_AdjustText( te, vScroll );
*dirty = 1;
}
else
{
FnErr_DisplayStr(
"\pPaste size too large.","\p","\p","\p", FALSE);
}
break;
case FnCLEAR:
TEDelete( *te );
FnTE_DetSBarIncr( te, vScroll );
FnTE_SetToCursorPos( te, vScroll );
FnTE_AdjustText( te, vScroll );
*dirty = 1;
break;
case FnSELECT_ALL:
TESetSelect( 0, 32767, *te );
FnTE_SetToCursorPos( te, vScroll );
FnTE_AdjustText( te, vScroll );
break;
}
}
/********** DoContent */
void FnTE_DoContent( WindowPtr w,
EventRecord *e,
TEHandle *te,
ControlHandle *vScroll )
/*
Use this procedure when user clicks in content region of TE window.
Uses the TnTE_ScrollProc below to take care of scroll bar function.
Also uses FnTE_AdjustText function.
*/
{
int cntlCode;
ControlHandle cntl;
int pageSize;
GrafPtr savePort;
GetPort(&savePort);
SetPort(w);
GlobalToLocal(&e->where);
if( (cntlCode = FindControl(e->where, w, &cntl)) == 0 )
{
if( PtInRect( e->where, &(***te).viewRect) )
{
TEClick( e->where, (e->modifiers & shiftKey) != 0, *te );
FnTE_CheckScrollBar( te, vScroll );
}
}
else if( cntlCode == inThumb )
{
TrackControl( cntl, e->where, 0L );
FnTE_AdjustText( te, vScroll );
}
else
{
tempTEHptr = te;
tempVScrollptr = vScroll;
TrackControl( cntl, e->where, FnTE_ScrollProc );
}
SetPort(savePort);
}
/********** DetSBarIncr */
void FnTE_DetSBarIncr( TEHandle *te, ControlHandle *vScroll )
/*
Determines number of scroll bar increments based on amount of
text pointed to in TEHandle te.
*/
{
register int nIncr, nLinesDisplayed, len;
nLinesDisplayed = ((***te).viewRect.bottom-(***te).viewRect.top) /
(***te).lineHeight;
nIncr = (***te).nLines - nLinesDisplayed;
len = (***te).teLength;
if( len <= 1 ) len = 1;
if( (*((***te).hText))[len-1] == '\r' )
nIncr++;
if( nIncr < 0 )
nIncr = 0;
if( nIncr != GetCtlMax( *vScroll ) )
SetCtlMax( *vScroll, nIncr );
}
/********** GrowWindow */
void FnTE_GrowWindow( WindowPtr w,
TEHandle *te,
ControlHandle *vScroll,
short textInsetPixels,
Point clickLoc )
/*
Use this function to resize a TE window.
*/
{
GrafPtr savePort;
long theResult;
Rect oldHorizBar;
Rect r;
int SBarWidth = 15;
float percent;
float currentValue;
float currentMax;
GetPort( &savePort );
SetPort( w );
// although not used, calculate size of bottom scroll bar
oldHorizBar = w->portRect;
oldHorizBar.top = oldHorizBar.bottom - (SBarWidth + 1);
currentValue = GetCtlValue( *vScroll );
currentMax = GetCtlMax( *vScroll );
if( currentMax > 0 )
percent = currentValue / currentMax;
else
percent = 0.0;
SetRect( &r, 100, 100, qd.screenBits.bounds.right,
qd.screenBits.bounds.bottom );
theResult = GrowWindow( w, clickLoc, &r );
if (theResult == 0)
return;
SizeWindow( w, LoWord(theResult), HiWord(theResult), FALSE );
InvalRect( &w->portRect );
EraseRect( &w->portRect );
(***te).viewRect = w->portRect;
(***te).viewRect.right -= SBarWidth;
(***te).viewRect.bottom -= SBarWidth;
InsetRect( &(***te).viewRect, textInsetPixels, textInsetPixels );
(***te).destRect = (***te).viewRect;
TECalText( *te );
MoveControl( *vScroll,
w->portRect.right - SBarWidth,
w->portRect.top - 1 );
SizeControl( *vScroll,
SBarWidth + 1,
w->portRect.bottom - w->portRect.top - (SBarWidth-2) );
FnTE_DetSBarIncr( te, vScroll );
percent = percent * (float)GetCtlMax( *vScroll );
SetCtlValue( *vScroll, int( percent ) );
FnTE_AdjustText( te, vScroll );
DrawGrowIcon( w );
TEUpdate( &w->portRect, *te );
ValidRect( &w->portRect );
SetPort( savePort );
}
/********** FrameRect */
void FnTE_FrameRect( WindowPtr w, TEHandle *te, short inset )
{
Rect itemRect;
PenState thePnState;
GrafPtr oldPort;
GetPort( &oldPort );
SetPort( w );
itemRect = (***te).viewRect;
InsetRect( &itemRect, -inset, -inset );
itemRect.right += 1;
GetPenState( &thePnState );
PenNormal();
FrameRect( &itemRect );
SetPenState( &thePnState );
SetPort( oldPort );
}
/********** GetTEXT */
void FnTE_GetTEXT( short rsrcID, TEHandle *te, ControlHandle *vScroll )
/*
Reads in TEXT resource into TE record and resets scroll bar. Need
to call FnTE_UpdateWindow to display text.
*/
{
(**te)->hText = GetResource( 'TEXT', rsrcID );
TECalText( *te );
(***te).destRect.top = (***te).viewRect.top;
SetCtlValue( *vScroll, GetCtlMin( *vScroll ) );
FnTE_DetSBarIncr( te, vScroll );
}
/********** AdjustText */
void FnTE_AdjustText( TEHandle *te, ControlHandle *vScroll )
/*
Takes current value of the scroll bar position and adjusts text
for specified TextEdit pane. Call this function after user
clicks in scroll bar.
*/
{
int oldScroll, newScroll, delta;
oldScroll = (***te).viewRect.top - (***te).destRect.top;
newScroll = GetCtlValue( *vScroll ) * (***te).lineHeight;
delta = oldScroll - newScroll;
if( delta != 0 )
TEScroll( 0, delta, *te );
}
/********** SetToCursorPos */
void FnTE_SetToCursorPos( TEHandle *te, ControlHandle *vScroll )
/*
Use this function to adjust scroll bar position such that the
currently selected text and/or insertion cursor position is
displayed in middle of te window. You must make a call to a
function like FnTE_AdjustText after calling this function to redraw
text based on new scroll bar position.
*/
{
register int topLine,bottomLine,theLine,nIncr,nLinesDisplayed,len;
// following could be replaced by call to FnDetSBarIncr
nLinesDisplayed = ((***te).viewRect.bottom-(***te).viewRect.top) /
(***te).lineHeight;
nIncr = (***te).nLines - nLinesDisplayed;
len = (***te).teLength;
if( len <= 1 ) len = 1;
if( (*((***te).hText))[len-1] == '\r' )
nIncr++;
if( nIncr < 0 )
nIncr = 0;
SetCtlMax( *vScroll, nIncr );
topLine = GetCtlValue( *vScroll );
bottomLine = topLine + nLinesDisplayed;
if( (***te).selStart < (***te).lineStarts[topLine] ||
(***te).selStart >= (***te).lineStarts[bottomLine] )
{
for( theLine = 0;
(***te).selStart >= (***te).lineStarts[theLine];
theLine++ )
/* count */ ;
SetCtlValue( *vScroll, theLine - nLinesDisplayed / 2 );
}
}
/********** CheckScrollBar */
void FnTE_CheckScrollBar( TEHandle *te, ControlHandle *vScroll )
/*
Use this function to check (and adjust) scroll bar such that the
current top of the TE window matches the scroll bar increment. This
should be called when a mouseDown occurs in a TE window which has
auto scrolling enabled.
*/
{
register int incr;
incr = ((***te).viewRect.top-(***te).destRect.top) /
(***te).lineHeight;
if( incr < 0 )
incr = 0;
if( incr > GetCtlMax( *vScroll ) )
incr = GetCtlMax( *vScroll );
if( incr != GetCtlValue( *vScroll ) )
SetCtlValue( *vScroll, incr );
}
/********** PASCAL ScrollProc */
pascal void FnTE_ScrollProc( ControlHandle theControl, short theCode )
/*
Scroll procedure used for TE scroll bar. Uses FnTE_AdjustText
function to update text.
*/
{
int pageSize;
int scrollAmt;
int oldCtl;
if( theCode == 0 )
return;
pageSize =
((***tempTEHptr).viewRect.bottom -
(***tempTEHptr).viewRect.top) /
(***tempTEHptr).lineHeight - 1;
switch( theCode )
{
case inUpButton:
scrollAmt = -1;
break;
case inDownButton:
scrollAmt = 1;
break;
case inPageUp:
scrollAmt = -pageSize;
break;
case inPageDown:
scrollAmt = pageSize;
break;
}
oldCtl = GetCtlValue( theControl );
SetCtlValue( theControl, oldCtl + scrollAmt );
FnTE_AdjustText( tempTEHptr, tempVScrollptr );
}
// End of File